﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

using EnvDTE;
using EnvDTE100;

namespace Artisteer_Project_Converter.VisualStudioApi
{
    public class VisualStudio : IDisposable
    {
        DTE dte = null;
        VsSolution solution = null;

        bool isDisposed = false;

        /// <summary>
        /// Create new instance of Visual Studio
        /// </summary>
        /// <param name="visible">Visibility of Visual Studio instance</param>
        public VisualStudio(bool visible = true)
        {
            dte = (DTE)Microsoft.VisualBasic.Interaction.CreateObject("VisualStudio.DTE.10.0", "");
        }

        /// <summary>
        /// Create a new solution
        /// </summary>
        /// <param name="path">Target path</param>
        /// <param name="name">Solution name</param>
        /// <returns>Solution</returns>
        public VsSolution CreateSolution(string path, string name)
        {
            Solution.CreateSolution(path, name);

            return Solution;
        }

        /// <summary>
        /// Close instance of Visual Studio
        /// </summary>
        public void Dispose()
        {
            if (!isDisposed)
            {
                if (dte != null)
                {
                    while (true)
                    {
                        try
                        {
                            dte.Quit();
                            dte = null;
                            break;
                        }
                        catch (COMException ex)
                        {
                            if (ex.ErrorCode == -2147418111)
                                System.Threading.Thread.Sleep(100);
                            else
                                throw ex;
                        }
                    }
                }

                solution = null;
                isDisposed = true;
            }
        }

        /// <summary>
        /// Get current solution
        /// </summary>
        public VsSolution Solution
        {
            get
            {
                if (solution == null) solution = new VsSolution((Solution4)dte.Solution);
                return solution;
            }
        }

        /// <summary>
        /// Windows State of Application
        /// </summary>
        public vsWindowState WindowState
        {
            get
            {
                while (true)
                {
                    try
                    {
                        return dte.MainWindow.WindowState;
                    }
                    catch (COMException ex)
                    {
                        if (ex.ErrorCode == -2147418111)
                            System.Threading.Thread.Sleep(100);
                        else
                            throw ex;
                    }
                }
            }

            set
            {
                while (true)
                {
                    try
                    {
                        dte.MainWindow.WindowState = value;
                        break;
                    }
                    catch (COMException ex)
                    {
                        if (ex.ErrorCode == -2147418111)
                            System.Threading.Thread.Sleep(100);
                        else
                            throw ex;
                    }
                }
            }
        }

        /// <summary>
        /// Visibility of Application
        /// </summary>
        public bool Visible
        {
            get
            {
                while (true)
                {
                    try
                    {
                        return dte.MainWindow.Visible;
                    }
                    catch (COMException ex)
                    {
                        if (ex.ErrorCode == -2147418111)
                            System.Threading.Thread.Sleep(100);
                        else
                            throw ex;
                    }
                }
            }

            set
            {
                while (true)
                {
                    try
                    {
                        dte.MainWindow.Visible = value;
                        break;
                    }
                    catch (COMException ex)
                    {
                        if (ex.ErrorCode == -2147418111)
                            System.Threading.Thread.Sleep(100);
                        else
                            throw ex;
                    }
                }
            }
        }
    }
}
